package com.alfy.websocketdemo.demo2;

import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;

/**
 * WebSocket 服务端
 */
public class WebSocketServerDemo extends WebSocketServer {


    /**
     * 客户端 握手 对象
     */
    ClientHandshake clientHandshake = null;

    /**
     * 通过端口创建 socket 服务
     *
     * @param port port
     */
    public WebSocketServerDemo(int port) {
        super(new InetSocketAddress(port));
    }

    /**
     * 通过 InetSocketAddress 创建 socket 服务
     *
     * @param address address
     */
    public WebSocketServerDemo(InetSocketAddress address) {
        super(address);
    }

    /**
     * start 事件
     */
    @Override
    public void onStart() {
        System.out.println("服务端已启动 ~~~~~~~~~~~~");
        // 间隔检查丢失连接的 Setter 值低于或等于 0 会导致检查被停用
        // 参数： connectionLostTimeout – 以秒为单位的间隔
        setConnectionLostTimeout(0);
        setConnectionLostTimeout(100);
    }

    /**
     * open 事件
     *
     * @param conn
     * @param handshake
     */
    @Override
    public void onOpen(WebSocket conn, ClientHandshake handshake) {
        clientHandshake = handshake;
        String hostAddress = conn.getRemoteSocketAddress().getAddress().getHostAddress();
        System.out.println(hostAddress + " 进入房间");
        // 此方法向新客户端发送消息
        conn.send("欢迎使用服务器");
        // 此方法向所有连接的客户端发送消息
        broadcast("新连接: " + handshake.getResourceDescriptor());
    }

    /**
     * message 事件
     *
     * @param conn
     * @param message message
     */
    @Override
    public void onMessage(WebSocket conn, String message) {
        // 向所有连接的端点发送文本 Params： text – 要发送到端点的文本
        broadcast(message);
        String hostAddress = conn.getRemoteSocketAddress().getAddress().getHostAddress();
        System.out.println(hostAddress + ": " + message);
    }

    /**
     * close 事件
     *
     * @param conn
     * @param code
     * @param reason
     * @param remote remote
     */
    @Override
    public void onClose(WebSocket conn, int code, String reason, boolean remote) {
        String hostAddress = conn.getRemoteSocketAddress().getAddress().getHostAddress();
        System.out.println(hostAddress + " 已经离开了房间");
        broadcast(hostAddress + " 已经离开了房间");
    }

    /**
     * error 事件
     *
     * @param conn
     * @param ex   ex
     */
    @Override
    public void onError(WebSocket conn, Exception ex) {
        ex.printStackTrace();
        if (conn != null) {
            // some errors like port binding failed may not be assignable to a specific
            // websocket
        }
    }

    public static void main(String[] args) throws InterruptedException, IOException {
        WebSocketServerDemo webSocketServerDemo = new WebSocketServerDemo(8889);
        // 启动服务器选择器线程，该线程绑定到当前设置的端口号和 WebSocket 连接请求的侦听器。
        // 创建一个固定线程池，其大小为 AVAILABLE_PROCESSORS 只能调用一次。或者，您可以直接调用 run（）。
        // Throws: IllegalStateException – 再次启动实例
        webSocketServerDemo.start();
        System.out.println("ChatServer 在端口上启动: " + webSocketServerDemo.getPort());
        // 获取控制台输入流
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            String in = bufferedReader.readLine();
            webSocketServerDemo.broadcast(in);
            if (in.equals("exit")) {
                webSocketServerDemo.stop(1000);
                break;
            }
        }
    }

}

// ChatServer 在端口上启动: 8889
// 服务端已启动 ~~~~~~~~~~~~
// 127.0.0.1 进入房间
// 127.0.0.1: Hello, I am WebSocket Client1
// 127.0.0.1 进入房间
// 127.0.0.1 已经离开了房间
